package cn.elwy.osgi.logger;

import java.io.File;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.util.StatusPrinter;
import cn.elwy.common.exception.RunException;
import cn.elwy.common.log.LogConfig;
import cn.elwy.osgi.config.Constant;
import cn.elwy.osgi.config.util.ResourceUtil;

/**
 * 日志配置类
 * @author huangsq
 * @version 1.0, 2012-10-31
 * @since 1.0, 2012-10-31
 */
public class LoggerConfig implements Constant, Serializable {

  private static final long serialVersionUID = 1L;

  private static LoggerConfig instance;

  private LoggerContext loggerContext;
  private File loggerConfigFile = null;
  private File logbackFile = null;

  private LoggerConfig() {
    init();
  }

  public synchronized static LoggerConfig getInstance() {
    if (instance == null) {
      instance = new LoggerConfig();
    }
    return instance;
  }

  /**
   * 初始化
   */
  private void init() {
    logbackFile = ResourceUtil.getResourcesFile(this.getClass(), LOGBACK_FILE);
    loggerConfigFile = ResourceUtil.getResourcesFile(this.getClass(), LOGGER_CONFIG_FILE);
    System.setProperty("loggerConfig.properties", loggerConfigFile.getAbsolutePath());
  }

  /**
   * 配置生效
   */
  public synchronized void doConfig() {
    try {
      loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
      JoranConfigurator configurator = new JoranConfigurator();
      configurator.setContext(loggerContext);
      loggerContext.reset();
      configurator.doConfigure(logbackFile);
      StatusPrinter.print(loggerContext);
      LogConfig.init();
    } catch (Exception e) {
      throw new RunException(e.getMessage(), e);
    } finally {
      StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
    }
  }

  public Appender<ILoggingEvent> getMemoryBufferAppender() {
    return loggerContext.getLogger("root").getAppender("WEB-CONSOLE-OUT");
  }

  public synchronized void stop() {
    try {
      List<Logger> list = loggerContext.getLoggerList();
      for (Logger logger : list) {
        Iterator<Appender<ILoggingEvent>> it = logger.iteratorForAppenders();
        while (it.hasNext()) {
          Appender<ILoggingEvent> appender = it.next();
          appender.clearAllFilters();
          appender.stop();
          appender = null;
        }
      }
    } catch (Throwable e) {
      System.out.println(e.getMessage());
    }
    if (!loggerContext.isStarted())
      loggerContext.stop();

    loggerContext.getStatusManager().clear();
    try {
      loggerContext.getExecutorService().shutdown();
    } catch (Throwable e) {
    }
    loggerContext = null;
  }

  public LoggerContext getLoggerContext() {
    return loggerContext;
  }

  public File getLoggerConfigFile() {
    return loggerConfigFile;
  }

  public void setLoggerConfigFile(File loggerConfigFile) {
    this.loggerConfigFile = loggerConfigFile;
  }

  public File getLogbackFile() {
    return logbackFile;
  }

  public void setLogbackFile(File logbackFile) {
    this.logbackFile = logbackFile;
  }

}
